package com.cango.student.lthread;

/**
 * 唤醒wait
 * wait是指在一个已经进入了同步锁的线程内，让自己暂时让出同步锁，以便其他正在等待此锁的线程可以得到同步锁并运行，
 * 只有其他线程调用了notify方法（notify并不释放锁，只是告诉调用过wait方法的线程可以去参与获得锁的竞争了，但不是马上得到锁，因为锁还在别人手里，别人还没释放），
 * 调用wait方法的一个或多个线程就会解除wait状态，重新参与竞争对象锁，程序如果可以再次得到锁，就可以继续向下运行。
 */
public class TestNotifyall {
    public static Object object = new Object();
    public static void main(String[] args) {
        Thread1 thread1 = new Thread1();
        Thread2 thread2 = new Thread2();

        thread1.start();

        try {
            Thread.sleep(200);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        thread2.start();
    }

    static class Thread1 extends Thread{
        @Override
        public void run() {
            synchronized (object) {
                try {
                    // 如果调用某个对象的wait()方法，当前线程必须拥有这个对象的monitor（即锁），
                    // 因此调用wait()方法必须在同步块或者同步方法中进行（synchronized块或者synchronized方法）。
                    System.out.println(System.currentTimeMillis());
                    sleep(5000);
                    System.out.println("wait");
                    object.wait();
                } catch (InterruptedException e) {
                }
                System.out.println("线程"+Thread.currentThread().getName()+"获取到了锁");
            }
        }
    }

    static class Thread2 extends Thread{
        @Override
        public void run() {
            synchronized (object) {
                // 调用某个对象的notify()方法，当前线程也必须拥有这个对象的monitor，
                // 因此调用notify()方法必须在同步块或者同步方法中进行（synchronized块或者synchronized方法）。
                System.out.println(System.currentTimeMillis());
                object.notify();
                System.out.println("线程"+Thread.currentThread().getName()+"调用了object.notify()");
            }
            System.out.println("线程"+Thread.currentThread().getName()+"释放了锁");
        }
    }
}
